package com.ruoyi.pos.service.impl.shift;

import com.ruoyi.pos.domain.cashier.PosCashier;
import com.ruoyi.pos.domain.dto.shift.request.ShiftReportRequest;
import com.ruoyi.pos.domain.dto.shift.response.ShiftReportResponse;
import com.ruoyi.pos.domain.dto.shift.response.ShiftReportDetail;
import com.ruoyi.pos.domain.transaction.PosSale;
import com.ruoyi.pos.domain.transaction.PosSaleDetail;
import com.ruoyi.pos.mapper.transaction.PosSaleMapper;
import com.ruoyi.pos.mapper.transaction.PosSaleDetailMapper;
import com.ruoyi.pos.mapper.cashier.PosCashierMapper;
import com.ruoyi.pos.mapper.device.PosDeviceMapper;
import com.ruoyi.pos.mapper.system.PosGroupMapper;
import com.ruoyi.pos.service.shift.IPosShiftService;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;

/**
 * POS交班管理Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-01-30
 */
@Service
@Transactional(transactionManager = "posTransactionManager")
public class PosShiftServiceImpl implements IPosShiftService {

    private static final Logger logger = LoggerFactory.getLogger(PosShiftServiceImpl.class);

    @Autowired
    private PosSaleMapper posSaleMapper;

    @Autowired
    private PosSaleDetailMapper posSaleDetailMapper;

    @Autowired
    private PosCashierMapper posCashierMapper;

    @Autowired
    private PosDeviceMapper posDeviceMapper;

    @Autowired
    private PosGroupMapper posGroupMapper;

    /**
     * 生成班报
     * 
     * @param request 班报请求
     * @return 班报响应
     */
    @Override
    public ShiftReportResponse generateShiftReport(ShiftReportRequest request) {
        ShiftReportResponse response = new ShiftReportResponse();
        response.setGenerateTime(new Date());
        response.setCashierCode(request.getCashierCode());
        response.setDeviceCode(request.getDeviceCode());
        response.setReportType("SHIFT");
        response.setReportStartTime(request.getShiftStartTime());
        response.setReportEndTime(request.getShiftEndTime());

        try {
            // 查询班次期间的销售数据
            List<ShiftReportDetail> details = queryShiftReportDetails(request);
            response.setDetails(details);

            // 计算汇总信息
            int totalTransactions = details.size();
            BigDecimal totalAmount = details.stream()
                    .map(ShiftReportDetail::getAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            response.setTotalTransactions(totalTransactions);
            response.setTotalAmount(totalAmount);

            // 获取收银员姓名
            if (StringUtils.isNotEmpty(request.getCashierCode())) {
                PosCashier cashier = posCashierMapper.selectPosCashierByCode(request.getCashierCode());
                if (cashier != null) {
                    response.setCashierName(cashier.getCashierName());
                }
            }

        } catch (Exception e) {
            // 处理异常
            response.setDetails(new ArrayList<>());
            response.setTotalTransactions(0);
            response.setTotalAmount(BigDecimal.ZERO);
        }

        return response;
    }

    /**
     * 生成日报
     * 
     * @param request 日报请求
     * @return 日报响应
     */
    @Override
    public ShiftReportResponse generateDailyReport(ShiftReportRequest request) {
        ShiftReportResponse response = new ShiftReportResponse();
        response.setGenerateTime(new Date());
        response.setCashierCode(request.getCashierCode());
        response.setDeviceCode(request.getDeviceCode());
        response.setReportType("DAILY");
        response.setReportStartTime(request.getReportDate());
        response.setReportEndTime(request.getReportDate());

        try {
            // 查询日报期间的销售数据
            List<ShiftReportDetail> details = queryDailyReportDetails(request);
            response.setDetails(details);

            // 计算汇总信息
            int totalTransactions = details.size();
            BigDecimal totalAmount = details.stream()
                    .map(ShiftReportDetail::getAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            response.setTotalTransactions(totalTransactions);
            response.setTotalAmount(totalAmount);

            // 获取收银员姓名
            if (StringUtils.isNotEmpty(request.getCashierCode())) {
                PosCashier cashier = posCashierMapper.selectPosCashierByCode(request.getCashierCode());
                if (cashier != null) {
                    response.setCashierName(cashier.getCashierName());
                }
            }

        } catch (Exception e) {
            // 处理异常
            response.setDetails(new ArrayList<>());
            response.setTotalTransactions(0);
            response.setTotalAmount(BigDecimal.ZERO);
        }

        return response;
    }

    /**
     * 查询班报明细数据
     * 
     * @param request 班报请求
     * @return 班报明细列表
     */
    private List<ShiftReportDetail> queryShiftReportDetails(ShiftReportRequest request) {
        List<ShiftReportDetail> details = new ArrayList<>();
        
        try {
            // 1. 构建查询条件：根据收银员编码、设备编码、时间范围查询销售数据
            PosSale saleQuery = new PosSale();
            
            // 设置收银员条件
            if (request.getCashierCode() != null && !request.getCashierCode().isEmpty()) {
                // 注意：PosSale中可能使用userId字段存储收银员ID
                // 需要先根据cashierCode查询cashierId
                // saleQuery.setUserId(cashierId);
            }
            
            // 设置设备条件
            if (request.getDeviceCode() != null && !request.getDeviceCode().isEmpty()) {
                // saleQuery.setDeviceCode(request.getDeviceCode());
            }
            
            // 设置时间范围
            // 注意：需要在Mapper XML中实现时间范围查询
            // 这里使用reserved字段临时存储查询条件
            
            // 2. 查询销售主表数据
            List<PosSale> sales = posSaleMapper.selectPosSaleList(saleQuery);
            
            // 3. 遍历销售主表，查询明细并组装数据
            for (PosSale sale : sales) {
                // 查询该笔交易的明细
                List<PosSaleDetail> saleDetails = posSaleDetailMapper.selectPosSaleDetailByTransactionId(sale.getTransactionId());
                
                // 4. 组装报表明细
                for (PosSaleDetail detail : saleDetails) {
                    ShiftReportDetail reportDetail = new ShiftReportDetail();
                    
                    // 基础信息
                    reportDetail.setTransactionNo(sale.getTransactionNo());
                    reportDetail.setTransactionTime(sale.getTransactionTime());
                    reportDetail.setTransactionType(sale.getTransactionStatus());
                    
                    // 商品信息
                    reportDetail.setGoodsCode(detail.getGoodsCode());
                    reportDetail.setGoodsName(detail.getGoodsName());
                    reportDetail.setQuantity(detail.getQuantity());
                    reportDetail.setUnitPrice(detail.getUnitPrice());
                    reportDetail.setAmount(detail.getAmount());
                    
                    // 柜组信息（从商品信息中获取，或者关联查询）
                    // 注：需要根据实际表结构调整
                    // reportDetail.setGroupCode(...);
                    // reportDetail.setGroupName(...);
                    
                    details.add(reportDetail);
                }
            }
            
            logger.info("查询班报明细成功，共 {} 条记录", details.size());
            
        } catch (Exception e) {
            logger.error("查询班报明细失败", e);
        }
        
        return details;
    }

    /**
     * 查询日报明细数据
     * 
     * @param request 日报请求
     * @return 日报明细列表
     */
    private List<ShiftReportDetail> queryDailyReportDetails(ShiftReportRequest request) {
        List<ShiftReportDetail> details = new ArrayList<>();
        
        try {
            // 1. 构建查询条件：根据日期查询当天的所有销售数据
            PosSale saleQuery = new PosSale();
            
            // 设置日期条件（查询指定日期的所有交易）
            // 注意：需要在Mapper XML中实现日期范围查询
            // 这里假设使用createTime字段进行查询
            
            // 2. 查询销售主表数据（查询当天所有交易）
            List<PosSale> sales = posSaleMapper.selectPosSaleList(saleQuery);
            
            // 3. 遍历销售主表，查询明细并组装数据
            for (PosSale sale : sales) {
                // 查询该笔交易的明细
                List<PosSaleDetail> saleDetails = posSaleDetailMapper.selectPosSaleDetailByTransactionId(sale.getTransactionId());
                
                // 4. 组装报表明细
                for (PosSaleDetail detail : saleDetails) {
                    ShiftReportDetail reportDetail = new ShiftReportDetail();
                    
                    // 基础信息
                    reportDetail.setTransactionNo(sale.getTransactionNo());
                    reportDetail.setTransactionTime(sale.getTransactionTime());
                    reportDetail.setTransactionType(sale.getTransactionStatus());
                    
                    // 商品信息
                    reportDetail.setGoodsCode(detail.getGoodsCode());
                    reportDetail.setGoodsName(detail.getGoodsName());
                    reportDetail.setQuantity(detail.getQuantity());
                    reportDetail.setUnitPrice(detail.getUnitPrice());
                    reportDetail.setAmount(detail.getAmount());
                    
                    // 柜组信息（从商品信息中获取，或者关联查询）
                    // 注：需要根据实际表结构调整
                    // 可以从detail.getGroupCode()获取，或者关联PosGroup表
                    // reportDetail.setGroupCode(...);
                    // reportDetail.setGroupName(...);
                    
                    details.add(reportDetail);
                }
            }
            
            logger.info("查询日报明细成功，共 {} 条记录", details.size());
            
        } catch (Exception e) {
            logger.error("查询日报明细失败", e);
        }
        
        return details;
    }
}
